﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;

namespace KLTP2UI
{
	class ThreadsListBox : ListBox
	{
		private readonly List<VisualThread> _items2 = new List<VisualThread>();
		private void VisualItemChangedEventHandler(Object sender, VisualThread.VisualItemChangedEventArgs e)
		{
			var snd = sender as VisualThread;
			var idx = Visual2Item4Ref(snd);
			if (e.WhatChanged == VisualThread.Changeables.FriendlyName)
			{//ReSharper disable PossibleNullReferenceException
				if (snd.Visible)
					Items[idx] = snd.ToString();
			}
			else
			{
				if (snd.Visible)
					Items.Insert(idx, snd.ToString());
				else
					Items.RemoveAt(idx);
			}//ReSharper enable PossibleNullReferenceException
		}
		
		public VisualThread GetVisual(int index)
		{
			return _items2[index];
		}
		public void AddVisual(VisualThread item)
		{
			_items2.Add(item);
			Items.Add(item.ToString());
			item.VisualItemChanged += VisualItemChangedEventHandler;
		}
		public void Clear()
		{
			Items.Clear();
			_items2.Clear();
		}
		public int VisualCount()
		{
			return _items2.Count;
		}

		public int Item2Visual4Index(int idx)
		{
			var index = -1;
			for (var counter = 0; counter <= idx; counter++)
			{
				index++;
				while (!_items2[index].Visible)
					index++;
			}
			return index;
		}
		public int Visual2Item4Index(int idx)
		{
			var index = 0;
			for (var counter = idx - 1; counter >= 0; counter--)
				if (_items2[counter].Visible)
					index++;
			return index;
		}
		public int Visual2Item4Ref(VisualThread item)
		{
			return Visual2Item4Index(_items2.IndexOf(item));
		}

		public int SelectedVisualIndex
		{
			get { return Item2Visual4Index(SelectedIndex); }
		}
		public VisualThread SelectedVisual
		{
			get { return _items2[SelectedVisualIndex]; }
		}
	}

	class VisualThread
	{
		private readonly int _tid;
		private string _friendlyName;
		private bool _visible;

		public event EventHandler<VisualItemChangedEventArgs> VisualItemChanged;
		
		public VisualThread(int tid)
		{
			_tid = tid;
			_visible = true;
		}

		public string TidHex
		{
			get { return _tid.ToString("X"); }
		}
		public string TidDec
		{
			get { return _tid.ToString(CultureInfo.InvariantCulture); }
		}
		public string FriendlyName
		{
			get { return _friendlyName; }
			set
			{
				if (_friendlyName == value)
					return;
				_friendlyName = value;
				Evoke(Changeables.FriendlyName);
			}
		}
		public bool Visible
		{
			get { return _visible; }
			set
			{
				if (_visible == value)
					return;
				_visible = value;
				Evoke(Changeables.Visible);
			}
		}

		public override string ToString()
		{
			if (!_visible)
				return string.Empty;
			if (!string.IsNullOrWhiteSpace(_friendlyName))
				return TidHex + " - " + _friendlyName;
			return TidHex;
		}
		private void Evoke (Changeables prop)
		{
			if (VisualItemChanged != null)
				VisualItemChanged(this, new VisualItemChangedEventArgs(prop));
		}

		public enum Changeables
		{
			FriendlyName,
			Visible
		}

		public class VisualItemChangedEventArgs:EventArgs
		{
			public Changeables WhatChanged { get; private set; }
			public VisualItemChangedEventArgs(Changeables whatChanged)
			{
				WhatChanged = whatChanged;
			}
		}
	}

}
